package com.canxi.games.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.crypto.SecureUtil;
import com.canxi.common.core.page.TableDataInfo;
import com.canxi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.canxi.common.exception.ServiceException;
import com.canxi.common.helper.LoginHelper;
import com.canxi.games.domain.CxGames;
import com.canxi.games.domain.vo.CxGamesVo;
import com.canxi.games.service.ICxGamesService;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.canxi.games.domain.bo.CxGamesConfigBo;
import com.canxi.games.domain.vo.CxGamesConfigVo;
import com.canxi.games.domain.CxGamesConfig;
import com.canxi.games.mapper.CxGamesConfigMapper;
import com.canxi.games.service.ICxGamesConfigService;

import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.canxi.cxcommon.utils.PageUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.hutool.core.util.StrUtil;

/**
 * 游戏配置Service业务层处理
 *
 * @author ruoyi
 * @date 2024-08-21
 */
@RequiredArgsConstructor
@Service
public class CxGamesConfigServiceImpl  extends JoinServiceImpl<CxGamesConfigMapper, CxGamesConfig> implements ICxGamesConfigService {

    private final CxGamesConfigMapper baseMapper;

    @Override
    public TableDataInfo<CxGamesConfigVo> queryCxGamesConfigList(CxGamesConfigBo cxGamesConfigBo) {

        return PageUtils.buildDataInfo(this.baseMapper.queryCxGamesConfigList(PageUtils.buildPage(), BeanUtil.toBean(cxGamesConfigBo, CxGamesConfigVo.class)));
    }

    @Override
    public List<CxGamesConfigVo> queryCxGamesConfigAll(CxGamesConfigBo cxGamesConfigBo) {
        return this.baseMapper.queryCxGamesConfigList(BeanUtil.toBean(cxGamesConfigBo, CxGamesConfigVo.class));
    }

    /**
     * 获取当前用户的最后一个配置信息，在新增时，使用模板，
     * @param bo
     * @return
     */
    @Override
    public  CxGamesConfigVo  getConfigByUserId(CxGamesConfigBo bo) {
        /**
         * 获取当前用户的所有游戏配置信息
         */
        CxGamesConfigVo configVo = this.baseMapper.queryCxGamesConfigByUserId(bo.getUserId(), bo.getLevel());

        if(ObjectUtil.isNotNull(configVo)){
            /**
             * 如果此用户有游戏配置信息，说明此用户有自定义配置信息
             */

            return configVo;
        }
 else{
            /**
             * 此用户没有自定义配置信息,默认用户ID为0，
             */
            CxGamesConfigVo defaultConfigVo = this.baseMapper.queryCxGamesConfigByUserId("0", bo.getLevel());
            return defaultConfigVo;
        }
    }


    /**
     * 查询游戏配置
     */
    @Override
    public CxGamesConfigVo queryById(String id){

        return baseMapper.queryCxGamesConfigById(id);
    }

    /**
     * 查询游戏配置列表
     */
    @Override
    public TableDataInfo<CxGamesConfigVo> queryPageList(CxGamesConfigBo bo, PageQuery pageQuery) {
//        JoinLambdaWrapper<CxGamesConfig> lqw = buildQueryWrapper(bo);
//        Page<CxGamesConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
//        return TableDataInfo.build(result);
        /**
         * 判断是否为admin
         */
        if(LoginHelper.isAdmin()){

        }

        return PageUtils.buildDataInfo(this.baseMapper.queryCxGamesConfigList(PageUtils.buildPage(), BeanUtil.toBean(bo, CxGamesConfigVo.class)));
    }

    /**
     * 查询游戏配置列表
     */
    @Override
    public List<CxGamesConfigVo> queryList(CxGamesConfigBo bo) {
        JoinLambdaWrapper<CxGamesConfig> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private JoinLambdaWrapper<CxGamesConfig> buildQueryWrapper(CxGamesConfigBo bo) {
        Map<String, Object> params = bo.getParams();
        JoinLambdaWrapper<CxGamesConfig> lqw = joinLambdaQueryWrapper(CxGamesConfig.class);
        lqw.eq(StrUtil.isNotBlank(bo.getTenantId()), CxGamesConfig::getTenantId, bo.getTenantId());
        lqw.eq(StrUtil.isNotBlank(bo.getGameId()), CxGamesConfig::getGameId, bo.getGameId());
        lqw.eq(bo.getWidth() != null, CxGamesConfig::getWidth, bo.getWidth());
        lqw.eq(bo.getHeight() != null, CxGamesConfig::getHeight, bo.getHeight());
        lqw.eq(bo.getLevelCols() != null, CxGamesConfig::getLevelCols, bo.getLevelCols());
        lqw.eq(bo.getLevelRows() != null, CxGamesConfig::getLevelRows, bo.getLevelRows());
        lqw.eq(bo.getGroupCount() != null, CxGamesConfig::getGroupCount, bo.getGroupCount());
        lqw.eq(bo.getOneGroupCount() != null, CxGamesConfig::getOneGroupCount, bo.getOneGroupCount());
        lqw.eq(StrUtil.isNotBlank(bo.getImg()), CxGamesConfig::getImg, bo.getImg());
        lqw.eq(StrUtil.isNotBlank(bo.getUserId()), CxGamesConfig::getUserId, bo.getUserId());
        lqw.eq(bo.getLevel() != null, CxGamesConfig::getLevel, bo.getLevel());
        lqw.eq(bo.getLayerCount() != null, CxGamesConfig::getLayerCount, bo.getLayerCount());
        return lqw;
    }

    /**
     * 新增游戏配置
     */
    @Override
    public Boolean insertByBo(CxGamesConfigBo bo) {
        CxGamesConfig add = BeanUtil.toBean(bo, CxGamesConfig.class);
        validEntityBeforeSave(add,false);

        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改游戏配置
     */
    @Override
    public Boolean updateByBo(CxGamesConfigBo bo) {
        CxGamesConfig update = BeanUtil.toBean(bo, CxGamesConfig.class);

        CxGamesConfigVo vo = this.baseMapper.selectVoById(bo.getId());
        if(!StrUtil.equals(bo.getId(), vo.getId())){
            throw new ServiceException("关卡不能修改");
        }

        validEntityBeforeSave(update,true);
        return baseMapper.updateById(update) > 0;
    }


    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(CxGamesConfig entity,Boolean update){

        LambdaQueryWrapper<CxGamesConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CxGamesConfig::getUserId, entity.getUserId());
        List<CxGamesConfigVo> vos = this.baseMapper.selectVoList(wrapper);

        //TODO 做一些数据校验,如唯一约束
        /**
         * 如果用户ID 不存在，则设用户ID为0
         */
        if(StrUtil.isBlank(entity.getUserId())){
            entity.setUserId("0");
        }

        Set<String> set = Arrays.stream(entity.getImg().split(",")).collect(Collectors.toSet());
        if(set.size() != entity.getImgNum()){
            throw new ServiceException("图片数量与要求的数量不一致");
        }

        if(update){
            /**
             * 如果是修改，则此时获取当前对象，判断关卡
             */
            CxGamesConfigVo configVo = this.baseMapper.selectVoById(entity.getId());
            if(StrUtil.equals(entity.getId(), configVo.getId())){
                /**
                 * 如果相同，则说明没有修改关卡的等级
                 */


            }else{
                /**
                 * 如果不同，则需要验证关卡等级
                 */
                Set<Long> set1 = vos.stream().map(CxGamesConfigVo::getLevel).collect(Collectors.toSet());
                if(set1.contains(entity.getLevel())){
                    throw new ServiceException("关卡等级重复");
                }
            }

        }else{
            Set<Long> set1 = vos.stream().map(CxGamesConfigVo::getLevel).collect(Collectors.toSet());
            if(set1.contains(entity.getLevel())){
                throw new ServiceException("关卡等级重复");
            }

        }

        Optional<CxGamesConfigVo> max = vos.stream().max(Comparator.comparing(CxGamesConfigVo::getLevel));
        if(max.isPresent()){
            CxGamesConfigVo vo = max.get();
            /**
             * 如果是修改，则不能大于当前等级，如果是新增，则不能大于数据库最大等级+1
             */
            if(entity.getLevel() > vo.getLevel()+ (update?0:1)){
                throw new ServiceException("请按顺序设置关卡");
            }
        }

    }

    /**
     * 批量删除游戏配置
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
            /**
             * 获取所有要删除的配置信息
             */
            List<CxGamesConfigVo> vos = this.baseMapper.selectVoBatchIds(ids);

        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 获取当前用户游戏关卡
     */
    public  CxGamesConfigVo  getGameLevelByUserId(CxGamesConfigBo bo) {
        /**
         * 获取当前用户的所有游戏配置信息
         */
        CxGamesConfigVo configVo = this.baseMapper.queryCxGamesConfigByUserId(bo.getUserId(), bo.getLevel());

        if(ObjectUtil.isNotNull(configVo)){
            /**
             * 如果此用户有游戏配置信息，说明此用户有自定义配置信息
             */

            return configVo;
        }
        else{
            /**
             * 此用户没有自定义配置信息,默认用户ID为0，
             */
            CxGamesConfigVo defaultConfigVo = this.baseMapper.queryCxGamesConfigByUserId("0", bo.getLevel());
            return defaultConfigVo;
        }
    }






}
